package com.css.zfzx.sjcj.modules.jobschedule.service.impl;

import com.css.bpm.platform.constants.PlatformConstants;
import com.css.bpm.platform.utils.PlatformObjectUtils;
import com.css.bpm.platform.utils.PlatformSessionUtils;
import com.css.bpm.platform.utils.UUIDGenerator;
import com.css.zfzx.sjcj.common.division.service.MyDivisionService;
import com.css.zfzx.sjcj.common.vo.DivisionVo;
import com.css.zfzx.sjcj.modules.jobschedule.entity.enums.ScheduleReportEnum;
import com.css.zfzx.sjcj.modules.jobschedule.entity.po.JobScheduleReportPO;
import com.css.zfzx.sjcj.modules.jobschedule.repository.JobScheduleRepository;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

@Component
public class JobScheduleReportExcelImportHelper {

    private static final String separator = "\\r\\n|\\r|\\n|\\s";
    private final MyDivisionService divisionService;
    private final JobScheduleRepository jobScheduleRepository;

    private static Map<String, String> regionMap = new HashMap<>(0);

    @Autowired
    public JobScheduleReportExcelImportHelper(MyDivisionService divisionService,
                                              JobScheduleRepository jobScheduleRepository) {
        this.divisionService = divisionService;
        this.jobScheduleRepository = jobScheduleRepository;
        loadRegion();
    }

    private void loadRegion() {
        if (regionMap == null || regionMap.isEmpty()) {
            List<DivisionVo> provinces = divisionService.getAllProvince();
            if (provinces != null) {
                regionMap = provinces.stream()
                        .collect(Collectors.toMap(DivisionVo::getProvinceName, DivisionVo::getProvinceCode));
            }
        }
    }

    public Optional<XSSFSheet> getSheet(InputStream excelFile) throws IOException {
        XSSFWorkbook wb = new XSSFWorkbook(excelFile);
        return Optional.of(wb.getSheet("进度统计表"));
    }

    public List<String> getTaskNameList (XSSFSheet sheet) {
        List<String> taskNameList = new ArrayList<>();
        XSSFRow taskRow = sheet.getRow(2);
        Iterator<Cell> taskIter = taskRow.iterator();
        taskIter.forEachRemaining(t -> {
            String data = t.getStringCellValue();
            if (PlatformObjectUtils.isNotEmpty(data))
                taskNameList.add(data.replaceAll(separator, ""));
        });
        return taskNameList;
    }

    public List<JobScheduleReportPO> getData (XSSFSheet sheet, List<String> taskNameList) {
        List<JobScheduleReportPO> dataList = new ArrayList<>();
        Date now = Calendar.getInstance().getTime();
        String userId = PlatformSessionUtils.getUserId();
        Map<String, JobScheduleReportPO> validJobs = mapJobs();
        for (int i = 4; i < sheet.getLastRowNum(); i++) {
            XSSFRow row = sheet.getRow(i);
            JobScheduleReportPO po = null;
            for (int j = 2; j < row.getLastCellNum(); j++) {
                XSSFCell cell = row.getCell(j);
                cell.setCellType(CellType.STRING);
                String cellData = cell.getStringCellValue();
                int taskIndex = j / 2, itemIdx  = j % 2;
                if (itemIdx == 0) {
                    String regionName = row.getCell(0).getStringCellValue();
                    String taskName = taskNameList.get(taskIndex - 1);
                    String taskCode = ScheduleReportEnum.getTaskCode(taskName);
                    String regionCode = regionMap.get(regionName);
                    po = validJobs.get(getValidJobKey(regionCode, taskCode));
                    if (po == null) {
                        po = new JobScheduleReportPO();
                        po.setId(UUIDGenerator.getUUID());
                        po.setCreateTime(now);
                        po.setCreateUser(userId);
                        po.setReportId(PlatformConstants.N);
                        po.setIsValid(PlatformConstants.Y);
                        po.setReportId(ScheduleReportEnum.getReportId(taskName));
                    }
                    po.setTaskCode(taskCode);
                    po.setTaskName(taskName);
                    po.setQuantity(cellData);
                    po.setDivisionName(regionName);
                    po.setDivisionCode(regionCode);
                    po.setUpdateTime(now);
                } else {
                    if (po != null) {
                        po.setPercentage(cellData);
                        dataList.add(po);
                    }
                }
            }
        }
        return dataList;
    }

    private String getValidJobKey(String divisionCode, String taskCode) {
        return divisionCode + taskCode;
    }

    private Map<String, JobScheduleReportPO> mapJobs() {
        List<JobScheduleReportPO> validJobs = jobScheduleRepository.findAllByIsValid(PlatformConstants.Y);
        if (validJobs == null)
            return new HashMap<>(0);
        return validJobs.stream().collect(Collectors.toMap(k -> getValidJobKey(k.getDivisionCode(), k.getTaskCode()), v -> v));
    }

}
